package cn.xuqiudong.rpc.proxy.jdk;

import cn.xuqiudong.rpc.common.model.Invoker;
import cn.xuqiudong.rpc.protocol.Protocol;
import cn.xuqiudong.rpc.extension.XqdExtensionFactory;
import cn.xuqiudong.rpc.common.model.XqdRequest;
import cn.xuqiudong.rpc.serializer.XqdSerializer;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

/**
 * 描述:基于jdk动态代理的调用远程服务的过程
 * @author Vic.xu
 * @date 2022-02-23 9:40
 */
public class JdkProxyInvocation implements InvocationHandler {


    private static Protocol protocol = XqdExtensionFactory.defaultExtendFactory().getAdaptiveXqdExtension(Protocol.class);

    private XqdSerializer serializer = XqdExtensionFactory.defaultExtendFactory().getAdaptiveXqdExtension(XqdSerializer.class);


    private Invoker invoker;

    public JdkProxyInvocation( Class clazz) {
        this.invoker = new Invoker();
        invoker.setInterfaceName(clazz.getName());
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //方法名
        String methodName = method.getName();
        //参数类型
        Class<?>[] parameterTypes = method.getParameterTypes();
        //组装好rpc的请求参数
        XqdRequest request = new XqdRequest(invoker.getInterfaceName(), methodName, parameterTypes, args);
        invoker.setXqdRequest(request);

        //发送方法到远程服务
        Object result = protocol.send(invoker);

        //处理返回的结果： 此处使用序列化/发序列化对方法的返回值再次处理，是为了防止json反序列化时多层嵌套，内层泛型丢失 FIXME
        if (!serializer.selfDescribed()) {
            byte[] bytes = serializer.serialize(result);
            result = serializer.deserialize(bytes, method.getReturnType());
        }
        return result;
   }
}


